﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//int main()
//{
//	int a = 10;
//	printf("%d\n", sizeof(a)); //sizeof根据类型计算大小，a为整型，大小为4
//	printf("%d\n", sizeof a); //少了括号，结果还是4，目的是想说明sizeof不是函数，仅仅只是一个操作符
//	printf("%d\n", sizeof(int)); //给的是整型，结果大小为4
//	return 0;
//}


//int main()
//{
//	char arr1[3] = { 'a', 'b', 'c' };
//	char arr2[] = "abc";
//	printf("%d\n", strlen(arr1));//数组名不在sizeof后面，所以理解为首元素的地址，往后找'\0'，所以为随机值
//	printf("%d\n", strlen(arr2));//
//	printf("%d\n", sizeof(arr1));//arr1为数组名，所以在sizeof后面，计算的是所有元素的大小，大小3
//	printf("%d\n", sizeof(arr2));//4
//	return 0;
//}


//int main()
//{
//	int a[] = { 1,2,3,4 };
//	printf("%d\n", sizeof(a)); //a为数组名，在sizeof后面求的是整个数组的大小，16
//	printf("%d\n", sizeof(a + 0));//a为数组名，但是不是单独出现在sizeof后面，所以是首元素的地址，sizeof求地址的大小，值为4/8
//	printf("%d\n", sizeof(*a)); //a为首元素的地址，*a为1，1的类型为int，所以大小为4
//	printf("%d\n", sizeof(a + 1));//a为首元素的地址，+1，就是往后位移一个int类型的大小，所以值为4
//	printf("%d\n", sizeof(a[1]));//a[1] = *(a+1) = 2 , 所以大小为4
//	printf("%d\n", sizeof(&a));//a为数组名，&a取出的是整个数组的地址，而sizeof求地址的大小，所以值为4/8
//	printf("%d\n", sizeof(*&a));//*和&相互抵消，a为数组名，单独出现在sizeof后面，计算的是整个数组的大小，所以值为16
//	printf("%d\n", sizeof(&a + 1));//&a取出是整个数组的地址，+1后跳过整个数组，本质上还是指针，所以值为4/8
//	printf("%d\n", sizeof(&a[0]));//a[0] = *(a+0) = a = &a ,得到的是a的地址，大小为4/8
//	printf("%d\n", sizeof(&a[0] + 1));//&a，指向a的地址，也就是首元素的地址，+1后得到第二个元素的地址，大小为4/8
//	return 0;
//}


//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };
//	printf("%d\n", sizeof(arr)); //arr为数组名，单独出现在sizeof后面，则计算整个数组元素的大小，值为6
//	printf("%d\n", sizeof(arr + 0)); //arr为数组名，但并没有单独出现在sizeof后面，所以表示首元素的地址，所以值为4/8
//	printf("%d\n", sizeof(*arr)); //arr为数组名，*arr = 'a'，求大小，所以值为1
//	printf("%d\n", sizeof(arr[1])); //arr[1] = *(arr + 1) = 'b' , 求大小，所以值为1
//	printf("%d\n", sizeof(&arr)); //&arr取出的是整个数组的地址，本质上还是地址，sizeof求地址大小，所以值为4/8
//	printf("%d\n", sizeof(&arr + 1));//&arr取出整个数组的地址，+1后跳出整个数组，本质上还是指针，求大小，值为4/8
//	printf("%d\n", sizeof(&arr[0] + 1)); //arr[0] = *(arr + 1) = b = &b + 1 = c的地址，本质还是地址，求大小，值为4/8
//	return 0;
//}


//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };
//	printf("%d\n", strlen(arr)); //arr为首元素的地址，数据类型为字符数组，其中并没有'\0'，所以为随机值
//	printf("%d\n", strlen(arr + 0)); //arr为首元素的地址，+0，还是一样，值为随机值
//	//printf("%d\n", strlen(*arr)); //arr为首元素的地址，*arr = 'a',a的askii码值为97，程序报错
//	//printf("%d\n", strlen(arr[1])); //arr[1] = *(arr + 1) = 'b'，程序报错
//	printf("%d\n", strlen(&arr)); //&arr取出的是整个数组的地址，和第一个没区别，还是会往后找'\0',值为随机值
//	printf("%d\n", strlen(&arr + 1));//&arr取出的是整个数组的地址，+1后跳出数组，值为随机值
//	printf("%d\n", strlen(&arr[0] + 1)); //arr[0] = *(arr + 0) = &'a' + 1 的到'b'的地址，结果也为随机值，比第一个小1
//	return 0;
//}



//int main()
//{
//	char arr[] = "abcdef";
//	printf("%d\n", sizeof(arr)); //arr单独出现在sizeof后面，表示求的是整个数组的大小，包括'\0',7
//	printf("%d\n", sizeof(arr + 0)); //arr并没有单独出现在sizeof后面，所以arr为首元素的地址，sizeof求地址大小，值为4/8
//	printf("%d\n", sizeof(*arr)); //arr为首元素的地址，*arr = a ,a为char类型，所以值为1
//	printf("%d\n", sizeof(arr[1])); //arr[1] = *(arr+1) = b , b为char类型，所以值为1
//	printf("%d\n", sizeof(&arr)); //&arr,取出的是整个数组的地址，本质上还是地址，值为4/8
//	printf("%d\n", sizeof(&arr + 1)); //&arr+1，跳出整个数组，本质上还是地址，值为4/8
//	printf("%d\n", sizeof(&arr[0] + 1)); //arr[0] = *(arr+0) = &a+1 = b的地址，本质上还是地址，值为4/8 
//	return 0;
//}


//int main()
//{
//	char arr[] = "abcdef";
//	printf("%d\n", strlen(arr)); //arr为首元素的地址，strlen就是往后找'\0'，值为6
//	printf("%d\n", strlen(arr + 0)); //arr为首元素地址，值为6
//	//printf("%d\n", strlen(*arr)); //*arr = a ,a的ascii码值为97，程序崩溃
//	//printf("%d\n", strlen(arr[1])); //arr[1] = *(arr + 1) = b , 程序崩溃
//	printf("%d\n", strlen(&arr)); //&arr取出的是整个数组的地址，和第一个没区别,值为6
//	printf("%d\n", strlen(&arr + 1)); //&arr+1,跳出数组范围，为随机值
//	printf("%d\n", strlen(&arr[0] + 1)); //arr[0] = *(arr+0) = &a+1=b的地址，值为5
//	return 0;
//}


//int main()
//{
//	char* p = "abcdef";
//	char arr[] = "abcdef";
//	printf("%d\n", sizeof(p)); //为指针,4/8
//	printf("%d\n", sizeof(p + 1)); //p并没有单独出现在sizeof后面，p为首元素的地址，+1后得到，b的地址，值为4/8
//	printf("%d\n", sizeof(*p));  //p为首元素的地址，*p的到a，a为char类型，值为1
//	printf("%d\n", sizeof(p[0]));  //p[0] = *(p+0) = a ,值为1
//	printf("%d\n", sizeof(&p));  //&p取出的是指针的地址，本质上还是地址，值为4/8
//	printf("%d\n", sizeof(&p + 1)); //&p+1，本质上还是地址，值为4/8
//	printf("%d\n", sizeof(&p[0] + 1)); //p[0] = *(p+0) = &a+1 = b的地址，本质还是地址，值为4/8
//	return 0;
//}


//int main()
//{
//	char* p = "abcdef";
//	printf("%d\n", strlen(p)); //p为指针，首元素的地址，值为6
//	printf("%d\n", strlen(p + 1)); //p + 1指向b，则值为5
//	//printf("%d\n", strlen(*p));  //*p = a ，ascii码值为97，程序崩溃
//	//printf("%d\n", strlen(p[0])); //p[0] = *(p+0) = a,程序崩溃
//	printf("%d\n", strlen(&p)); //p为指针，&p为指针的地址，所以为随机值
//	printf("%d\n", strlen(&p + 1)); //本质还是地址，所以为随机值
//	printf("%d\n", strlen(&p[0] + 1)); //p[0] = *(p+0) = &a + 1 = b的地址，所以值为5
//	return 0;
//}



//int main()
//{
//	int a[3][4] = { 0 };
//	printf("%d\n", sizeof(a));//a为数组名，单独出现在sizeof后面，表示求整个二维数组的大小，所以值为48
//	printf("%d\n", sizeof(a[0][0])); //a[0][0] = 0 ,类型为int，所以值为4
//	printf("%d\n", sizeof(a[0])); //a[0]为二维数组一行的数组名，单独出现在sizeof后面，求的是第一行数组的大小，16
//	printf("%d\n", sizeof(a[0] + 1)); //a[0]为二维数组第一行的数组名，没有单独出现在sizeof后面，则表示首元素的地址，+1得到第二个元素的地址，4/8
//	printf("%d\n", sizeof(*(a[0] + 1)));//4
//	printf("%d\n", sizeof(a + 1)); //a为数组名，没有单独出现在sizeof后面，所以a为首元素的地址，+1后跳过整个二维数组，本质上还是地址，值为4/8
//	printf("%d\n", sizeof(*(a + 1)));//a为数组名，但没有单独出现在sizeof之后，所以为首行的地址，+1后为第一行的地址，解引用得到第一行元素为16
//	printf("%d\n", sizeof(&a[0] + 1)); //a[0] = *(a+0) = &0 + 1 = 第零行第一列的地址，值为4/8
//	printf("%d\n", sizeof(*(&a[0] + 1)));//对第一行进行解引用，值为16
//	printf("%d\n", sizeof(*a)); //a为数组名，并没有单独出现在sizeof后面，所以为首行的地址，解引用后得到第零行的元素，值为16
//	printf("%d\n", sizeof(a[3]));//a[3] = *(a + 3) ,首行元素的地址，加三，得到第三行元素的地址，再解引用，得到第四行元素，值为16
//	return 0;
//}


#include <stdio.h>
//int main()
//{
//	int a[5] = { 1, 2, 3, 4, 5 };
//	int* ptr = (int*)(&a + 1);	
//	printf("%d,%d", *(a + 1), *(ptr - 1));
//	return 0;//2 5
//}

//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥？
//struct Test
//{
//	int Num;
//	char* pcName;
//	short sDate;
//	char cha[2];
//	short sBa[4];
//}*p = (struct Test*)0x100000;
//int main()
//{
//	printf("%p\n", p + 0x1); //0x100000 + 20 = 00100014 
//							 //此处环境为32位，每4位可以用一个十六进制表示，所以，总共是有8个十六进制，所以结果在前面补了两个0
//	printf("%p\n", (unsigned long)p + 0x1); //0x100000 + 1 = 00100001
//	printf("%p\n", (unsigned int*)p + 0x1); //0x100000 + 4 = 00100004
//	return 0;
//}



#include <stdio.h>
//int main()
//{
//	int a[3][2] = { (0, 1), (2, 3), (4, 5) }; // {{1,3}，{5,0}，{0,0}}
//	int* p;
//	p = a[0];
//	printf("%d", p[0]);//1
//	return 0;
//}


#include <stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}